package com.ruoyi.buy.service.impl;

import com.ruoyi.buy.domain.entity.PO.*;
import com.ruoyi.buy.domain.entity.inv0005.Inv0005InvDataDto;
import com.ruoyi.buy.domain.entity.inv0005.Inv0005PrintByIdVO;
import com.ruoyi.buy.domain.entity.inv0005.Inv0005UpdateByIdVO;
import com.ruoyi.buy.mapper.PO.*;
import com.ruoyi.buy.service.ICommonService;
import com.ruoyi.buy.service.IInvOutboundBillService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 出库单Service业务层处理
 * 
 * @author ruoyi
 * @date 2023-12-25
 */
@Service
@Transactional
public class InvOutboundBillServiceImpl implements IInvOutboundBillService
{
    @Resource
    private InvOutboundBillMapper invOutboundBillMapper;

    @Resource
    private InvOutboundBillItemMapper invOutboundBillItemMapper;

    @Resource
    private ICommonService commonService;

    @Resource
    private InvInventoryInfoMapper invInventoryInfoMapper;

    @Resource
    private InvInoutBillMapper invInoutBillMapper;

    @Resource
    private InvInoutBillItemMapper invInoutBillItemMapper;

    @Resource
    private BuyPurchaseBillMapper buyPurchaseBillMapper;


    /**
     * 查询出库单
     * 
     * @param id 出库单主键
     * @return 出库单
     */
    @Override
    public Inv0005UpdateByIdVO selectInvOutboundBillById(Long id)
    {
        Inv0005UpdateByIdVO result = new Inv0005UpdateByIdVO();
        result.setInvOutboundBill(invOutboundBillMapper.selectInvOutboundBillById(id));

        InvOutboundBillItem query = new InvOutboundBillItem();
        query.setnMainId(id);
        List<InvOutboundBillItem> invOutboundBillItemList = this.invOutboundBillItemMapper.selectInvOutboundBillItemList(query);
        result.setInvOutboundBillItemList(invOutboundBillItemList);
        return result;
    }

    /**
     * 查询出库单列表
     * 
     * @param invOutboundBill 出库单
     * @return 出库单
     */
    @Override
    public List<InvOutboundBill> selectInvOutboundBillList(InvOutboundBill invOutboundBill)
    {
        return invOutboundBillMapper.selectInvOutboundBillList(invOutboundBill);
    }

    /**
     * 新增出库单
     * 
     * @param para 出库单
     * @return 结果
     */
    @Override
    public int insertInvOutboundBill(Inv0005UpdateByIdVO para)
    {
       //先主表
        InvOutboundBill invOutboundBill = para.getInvOutboundBill();
        invOutboundBill.setIotype("O");
        invOutboundBill.setvType("OLL");
        invOutboundBill.setStatus("0");
        invOutboundBill.setCreateTime(DateUtils.getNowDate());
        invOutboundBill.setvBillNo(commonService.getNo("CK"));
        invOutboundBill.setOprBy(commonService.getUsername());
        this.invOutboundBillMapper.insertInvOutboundBill(invOutboundBill);
        invOutboundBill = this.invOutboundBillMapper.selectInvOutboundBillList(invOutboundBill).get(0);
        Long id = invOutboundBill.getId();

        //再子表
        List<InvOutboundBillItem> invOutboundBillItemList = para.getInvOutboundBillItemList();

        for (InvOutboundBillItem item: invOutboundBillItemList
             ) {
            item.setnMainId(id);
            item.setCreateTime(DateUtils.getNowDate());
            this.invOutboundBillItemMapper.insertInvOutboundBillItem(item);
        }
        return 1;
    }

    /**
     * 修改出库单
     * 
     * @param para 出库单
     * @return 结果
     */
    @Override
    public int updateInvOutboundBill(Inv0005UpdateByIdVO para)
    {
        InvOutboundBill invOutboundBill = para.getInvOutboundBill();
        invOutboundBill.setUpdateTime(DateUtils.getNowDate());
        invOutboundBillMapper.updateInvOutboundBill(invOutboundBill);

        Long id = invOutboundBill.getId();
        //再子表
        List<InvOutboundBillItem> invOutboundBillItemList = para.getInvOutboundBillItemList();
        for (InvOutboundBillItem item: invOutboundBillItemList
        ) {
            if (item.getId() == null || item.getId() == 0){
                item.setnMainId(id);
                item.setCreateTime(DateUtils.getNowDate());
                this.invOutboundBillItemMapper.insertInvOutboundBillItem(item);
            }else{
                InvOutboundBillItem search = new InvOutboundBillItem();
                search = this.invOutboundBillItemMapper.selectInvOutboundBillItemById(item.getId());
                if(search.getnQty() != item.getnQty()){
                    this.invOutboundBillItemMapper.updateInvOutboundBillItem(item);
                }
            }

        }
        return 1;
    }

    /**
     * 批量删除出库单
     * 
     * @param ids 需要删除的出库单主键
     * @return 结果
     */
    @Override
    public int deleteInvOutboundBillByIds(Long[] ids)
    {
        return invOutboundBillMapper.deleteInvOutboundBillByIds(ids);
    }

    /**
     * 删除出库单信息
     * 
     * @param id 出库单主键
     * @return 结果
     */
    @Override
    public int deleteInvOutboundBillById(Long id)
    {

        InvOutboundBill invOutboundBill = this.invOutboundBillMapper.selectInvOutboundBillById(id);
        invOutboundBill.setStatus("2");
        return this.invOutboundBillMapper.updateInvOutboundBill(invOutboundBill);
    }

    @Override
    public List<Inv0005InvDataDto> getInvDataList(Inv0005InvDataDto inv0005InvDataDto) {
        return invOutboundBillMapper.getInvDataList(inv0005InvDataDto);
    }

    @Override
    public int deleteInvOutboundBillItemById(InvOutboundBillItem para) {
        return invOutboundBillItemMapper.deleteInvOutboundBillItemById(para.getId());
    }

    @Override
    public String checkInvQty(InvOutboundBillItem para) {
        String result = "成功";
        BigDecimal nQty = para.getnQty();
        Inv0005InvDataDto inv0005InvDataDto = new Inv0005InvDataDto();
        BeanUtils.copyBeanProp(inv0005InvDataDto,para);
        inv0005InvDataDto.setnQty(null);
        Inv0005InvDataDto nowData = this.invOutboundBillMapper.getInvDataList(inv0005InvDataDto).get(0);
        if(nQty.compareTo(nowData.getnQty())>0){
            result = "库存数量不足，请确认";
        }
        return result;
    }

    @Override
    public String executeOut(Inv0005UpdateByIdVO para) throws Exception {
        String result = "成功";
        //库存数量校验
        List<InvOutboundBillItem> invOutboundBillItemList = para.getInvOutboundBillItemList();
        for (InvOutboundBillItem item:invOutboundBillItemList
             ) {
            BigDecimal nQty = item.getnQty();
            Inv0005InvDataDto inv0005InvDataDto = new Inv0005InvDataDto();
            BeanUtils.copyBeanProp(inv0005InvDataDto,item);
            inv0005InvDataDto.setnQty(null);
            Inv0005InvDataDto nowData = this.invOutboundBillMapper.getInvDataList(inv0005InvDataDto).get(0);
            if(nQty.compareTo(nowData.getnQty())>0){
                result = "物料:"+item.getvSpaName()+"库存数量不足，请确认";
                return result;
            }
        }
        //保存主子表信息
        InvOutboundBill invOutboundBill = para.getInvOutboundBill();
        invOutboundBill.setStatus("1");
        para.setInvOutboundBill(invOutboundBill);
        this.updateInvOutboundBill(para);

        //拆先入先出
        List<InvOutboundBillItem> list = new ArrayList<>();
        for (InvOutboundBillItem item:invOutboundBillItemList
        ) {
            InvInventoryInfo invInventoryInfo = new InvInventoryInfo();
            BeanUtils.copyBeanProp(invInventoryInfo,item);
            List<InvInventoryInfo> invInventoryInfos = this.invInventoryInfoMapper.selectInvInventoryInfoListOrderByLot(invInventoryInfo);
            BigDecimal nQty = item.getnQty();
            for (InvInventoryInfo info:invInventoryInfos
                 ) {
                if(nQty.compareTo(BigDecimal.ZERO)>0){
                    InvOutboundBillItem invOutboundBillItem = new InvOutboundBillItem();
                    BeanUtils.copyBeanProp(invOutboundBillItem,item);
                    if (nQty.compareTo(info.getnQty())>0){
                        nQty = nQty.subtract(info.getnQty());
                        invOutboundBillItem.setnQty(info.getnQty());
                    }else{
                        invOutboundBillItem.setnQty(nQty);
                        nQty = nQty.subtract(nQty);
                    }
                    invOutboundBillItem.setnPrice(info.getnPrice());
                    invOutboundBillItem.setvLotNo(info.getvLotNo());
                    list.add(invOutboundBillItem);
                }
            }
        }

        //改库存
        commonService.changeInventory(para.getInvOutboundBill(),new ArrayList<>(list),"OUT");

        return result;
    }

    @Override
    public Inv0005PrintByIdVO printOut(InvOutboundBill para) {

        InvOutboundBill invOutboundBill = this.invOutboundBillMapper.selectInvOutboundBillById(para.getId());
        InvInoutBill invInoutBill = new InvInoutBill();
        invInoutBill.setvCorBillNo(invOutboundBill.getvBillNo());
        List<InvInoutBill> invInoutBills = this.invInoutBillMapper.selectInvInoutBillList(invInoutBill);
        Long id = invInoutBills.get(0).getId();
        InvInoutBillItem invInoutBillItem = new InvInoutBillItem();
        invInoutBillItem.setnMainId(id);
        List<InvInoutBillItem> invInoutBillItems = this.invInoutBillItemMapper.selectInvInoutBillItemList(invInoutBillItem);
        Inv0005PrintByIdVO result = new Inv0005PrintByIdVO();
        result.setInvOutboundBill(invOutboundBill);
        result.setInvOutboundBillItemList(invInoutBillItems);
        return result;
    }

    @Override
    public List<Map> getApplys(String vProjectNo) {
        BuyPurchaseBill buyPurchaseBill = new BuyPurchaseBill();
        buyPurchaseBill.setvProjectNo(vProjectNo);
        List<BuyPurchaseBill> buyPurchaseBills = this.buyPurchaseBillMapper.selectBuyPurchaseBillList(buyPurchaseBill);
        List<String> list = buyPurchaseBills.stream().map(BuyPurchaseBill::getApplyBy).collect(Collectors.toList());
        list = list.stream().distinct().collect(Collectors.toList());
        List<Map> result = new ArrayList<>();
        for (String item:list
             ) {
            Map<String,String> map = new HashMap<>();
            map.put("value",item);
            map.put("label",item);
            result.add(map);
        }
        return result;
    }

    @Override
    public int updateInvOutboundBillStatus(InvOutboundBill invOutboundBill) {
        invOutboundBill.setUpdateBy(commonService.getUsername());
        invOutboundBill.setUpdateTime(DateUtils.getNowDate());
        this.invOutboundBillMapper.updateInvOutboundBill(invOutboundBill);
        return 1;
    }


}
